package impl_base

import (
	"context"
	"errors"
	"gitee.com/hasika/common-server/conn/inet"
	"gitee.com/hasika/common-server/option"
	"time"
)

func ListenWithRetry[T any](doOnce func(address string) (T, error), address string, option option.ListenRetryOption) (T, error) {
	if option.RetryInterval == 0 {
		option.RetryInterval = time.Millisecond * 10
	}
	if option.RetryTime == 0 {
		option.RetryTime = time.Second
	}
	var ret T
	ctx, cancel := context.WithTimeout(context.Background(), option.RetryTime)
	defer cancel()
	ticker := time.NewTicker(option.RetryInterval)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return ret, errors.New("listen time out")
		case <-ticker.C:
			oneRet, oneErr := doOnce(address)
			if oneErr != nil {
				inet.Log.Warnf("fail to listen once: %s", oneErr)
				continue
			}
			return oneRet, nil
		}
	}
}
